package com.lcu.wl.modules.sys.service.impl;

import com.lcu.wl.common.utils.Constant;
import com.lcu.wl.common.utils.MapUtils;
import com.lcu.wl.modules.sys.entity.Menu;
import com.lcu.wl.modules.sys.mapper.MenuMapper;
import com.lcu.wl.modules.sys.service.IMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lcu.wl.modules.sys.service.IRoleMenuService;
import com.lcu.wl.modules.sys.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <p>
 * 菜单管理 服务实现类
 * </p>
 *
 * @author wanglei
 * @since 2021-01-15
 */
@Service("menuServiceImpl")
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {

    @Value("${menu.top-menu-id}")
    private Long topMenuId;

    @Autowired
    private IUserService iUserService;

    @Autowired
    private IRoleMenuService iRoleMenuService;

    @Override
    public List<Menu> getUserMenuList(Long userId) {
        if (userId == Constant.SUPER_ADMIN){
            return getAllMenuList(null);
        }
        //用户菜单列表
        List<Long> menuIdList = iUserService.queryMenuIdByUserId(userId);
        return  getAllMenuList(menuIdList);
    }

    /**
     * 获取所有菜单列表
     * @param menuIdList
     * @return List<Menu>
     */
    private List<Menu> getAllMenuList(List<Long> menuIdList) {
        //查询根菜单列表
        List<Menu> menuList = queryListParentId(topMenuId, menuIdList);
        //递归获取子菜单
        getMenuTreeList(menuList,menuIdList);

        return menuList;
    }

    /**
     * 递归获取子菜单
     * @param menuList
     * @param menuIdList
     * @return List<Menu>
     */
    private List<Menu> getMenuTreeList(List<Menu> menuList, List<Long> menuIdList) {
        List<Menu> childMenuList = new ArrayList<>();

        for (Menu menu : menuList){
            //目录
            if (menu.getType() == Constant.MenuType.CATALOG.getValue()){
                menu.setChildren(getMenuTreeList(queryListParentId(menu.getMenuId(),menuIdList),menuIdList));
            }
            childMenuList.add(menu);
        }
        return childMenuList;
    }

    @Override
    public List<Menu> queryListParentId(Long parentId, List<Long> menuIdList) {
        List<Menu> menuList = selectListByParentId(parentId);
        if (menuIdList == null){
            return menuList;
        }

        List<Menu> userMenuList = new ArrayList<>();
        for (Menu menu : menuList){
            if (menuIdList.contains(menu.getMenuId())){
                userMenuList.add(menu);
            }
        }
        return userMenuList;
    }

    @Override
    public List<Menu> selectListByParentId(Long parentId) {
        return baseMapper.selectListByParentId(parentId);
    }

    @Override
    public List<Menu> getMenuTree(Long pid) {
        List<Menu> menus;
        if(pid != null && !pid.equals(0L)){
            //根据父节点，查询子菜单
            menus = baseMapper.selectListByParentId(pid);
        }else{
            //查询顶级菜单
            menus = baseMapper.selectByMap(new MapUtils().put("parent_id",pid));
        }
        return menus;
    }

    @Override
    public Set<Menu> getChildMenus(List<Menu> menuList, Set<Menu> menuSet) {
        for (Menu menu : menuList) {
            menuSet.add(menu);
            List<Menu> menus = baseMapper.selectByPid(menu.getMenuId());
            if(menus!=null && menus.size()!=0){
                getChildMenus(menus, menuSet);
            }
        }
        return menuSet;
    }

    @Override
    public List<Menu> getListParentId(Long parentId) {
        return baseMapper.selectListByParentId(parentId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long menuId) {
        Menu menu = this.getById(menuId);
        //删除菜单
        this.removeById(menuId);

        updateSubCount(menu.getParentId());

        //删除菜单与角色关联
        iRoleMenuService.removeByMap(new MapUtils().put("menu_id",menuId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(Menu menu) {
        this.save(menu);
        menu.setSubCount(0);
        updateSubCount(menu.getParentId());
    }

    /**
     * 更新子节点数目
     * @param menuId
     */
    private void updateSubCount(Long menuId) {
        if (menuId != null){
            int num = baseMapper.selectCountByPid(menuId);
            baseMapper.updateSubCount(num,menuId);
        }
    }

    @Override
    public List<Menu> queryNotButtonList() {
        return baseMapper.selectNotButtonList();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Menu menu) {
        Menu resources = this.getById(menu.getMenuId());

        Long oldPid = resources.getParentId();
        Long newPid = menu.getParentId();

        this.updateById(menu);

        updateSubCount(oldPid);
        updateSubCount(newPid);

    }
}
